﻿using Language.Resource;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using MoreLinq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Applet.ResponseDto;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Extension;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Domain.Repository.Interface.Sys;
using VisionCloud.Utility;

namespace VisionCloud.Service.Applet
{
    public class ProjectService
    {
        public IMsUserToProjectRepository MsUserToProjectRepository { get; set; }

        public IMsProjectRepository MsProjectRepository { get; set; }

        public ISysDistrictRepository SysDistrictRepository { get; set; }

        public IProjectQualificationRateRepository ProjectQualificationRateRepository { get; set; }

        private OperatorInfo tokenModel = OperatorProvider.Get();

        public IStringLocalizer<ServiceResource> Localizer { get; set; }

        public ICSMSTaskRepository CSMSTaskRepository { get; set; }

        public async Task<List<ProjectLocationDto>> QueryProjectLocations(QueryProjectLocationDto query)
        {
            if (tokenModel.IsCompanyAdmin)
            {
                var list = await MsProjectRepository.GetAll().Where(x => !x.IsDeleted && x.PubliceDate != null && (query.Status == null || query.Status == x.IsCanPull) && x.CompanyGuid == tokenModel.CompanyGuid)
                                                             .WhereIf(!string.IsNullOrEmpty(query.City) && query.City != "全国", x => x.City == query.City)
                                                             .WhereIf(!string.IsNullOrWhiteSpace(query.QueryValue), x => x.Name.Contains(query.QueryValue))
                                                             .Select(x => new ProjectLocationDto
                                                             {
                                                                 Address = x.Address,
                                                                 CityTown = x.City + x.Town,
                                                                 Latitude = x.Latitude,
                                                                 Longitude = x.Longitude,
                                                                 ProjectId = x.ProjectId,
                                                                 ProjectName = x.Name,
                                                             }).AsNoTracking().ToListAsync();
                return list;
            }
            else
                return await MsUserToProjectRepository.QueryProjectLocations(query, tokenModel.Id);
        }

        public async Task<ProjectBuildingInfoDto> GetProjectBuildingInfo(Guid projectId)
        {
            var project = await MsProjectRepository.GetByIdAsync(projectId);
            var detail = JsonConvert.DeserializeObject<List<Detail>>(project.Details);
            return new ProjectBuildingInfoDto
            {
                ProjectName = project.Name,
                Buildings = detail.Select(x => new Building { BuildingName = x.Building, Floors = x.Floor }).ToList(),
            };
        }

        public async Task<CityListDto> GetCityList(string query)
        {
            var result = new CityListDto();
            var allCity = (await SysDistrictRepository.WhereAsNoTrackingAsync(x => x.Level == DistrictLevelEnum.城市)).Select(y => new { y.Name, y.PinyinHeadChar, y.IsHot, y.Center });
            if (allCity?.Count() <= 0)
            {
                throw new OperationException("未找到城市信息");
            }

            result.CityList = allCity.Where(x => string.IsNullOrWhiteSpace(query) || x.Name.Contains(query)).OrderBy(x => x.PinyinHeadChar).GroupBy(x => x.PinyinHeadChar).ToDictionary(x => x.Key, y => y.Select(s => new CityCenter { Name = s.Name, Center = s.Center }).ToList());

            result.HotCitys.AddRange(allCity.Where(x => x.IsHot == true).Select(x => new CityCenter { Name = x.Name, Center = x.Center }).ToList());

            return result;
        }

        public async Task<ProjectQualificateDto> ProjectQualificationRates(PageRequest request)
        {
            if (request.Page < 1) return new ProjectQualificateDto { Total = 0, Datas = new List<ProjectQualificateInfo>() };
            var query = ProjectQualificationRateRepository.QueryProjectQualificationRates(tokenModel.CompanyGuid, tokenModel.Id, tokenModel.IsCompanyAdmin).WhereIf(!string.IsNullOrWhiteSpace(request.Keywords), x => x.ProjectName.Contains(request.Keywords));
            query = request.IsAscend ? query.OrderBy(x => x.QualificationRate) : query.OrderByDescending(x => x.QualificationRate);
            var total = query.Count();
            var skipValue = (request.Page - 1) * request.PageSize;
            var result = await query.Select(x => new ProjectQualificateInfo { ProjectId = x.ProjectId, ProjectName = x.ProjectName, QualificationRate = x.QualificationRate }).Skip(skipValue).Take(request.PageSize).ToListAsync();
            return new ProjectQualificateDto { Total = total, Datas = result };
        }

        public async Task<string> GetCityNameFromLocation(LocationDto locaton)
        {
            return await AddressHelper.GetCityFromLocation(locaton.Latitude, locaton.Longitude);
        }

        public async Task<LocationDto> GetLocationFromAddress(string address)
        {
            var (lat, lng) = await AddressHelper.GetLocationFromAddress(address);
            return new LocationDto { Latitude = lat, Longitude = lng };
        }

        /// <summary>
        /// 根据项目Id和楼栋名获取已测楼层
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetProjectFloorInfo(WxProjectBuildingDto query)
        {
            var project = await MsProjectRepository.GetByIdAsync(query.ProjectId);
            if (project == null)
            {
                return ApiResult.Success(Localizer["YB0064"].Value);
            }

            var detail = JsonConvert.DeserializeObject<List<Detail>>(project.Details);
            if (!detail.Exists(x => x.Building == query.BuildingName))
            {
                return ApiResult.Success(Localizer["YB0470"].Value);
            }

            var result = await CSMSTaskRepository.GetAll().Where(x => x.ProjectId == query.ProjectId && x.BuildingName == query.BuildingName && !x.IsDeleted && x.MeasureType == ((int)query.MeasureType).ToString()).Select(x => new WxProjectFloorResponse { ProjectId = x.ProjectId.Value, BuildingName = x.BuildingName, FloorName = x.FloorName }).ToListAsync();

            return ApiResult.Success().SetData(result);
        }
    }
}